package com.service.question.common.interceptor;

import com.huawei.questionnaire.resources.api.SatisfactionApi;
import com.service.question.common.utils.IpUtils;
import com.service.question.common.utils.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author: hjl
 * @date: 2022/03/11
 * @description:防恶意访问拦截类
 */
@Component
public class IpUrlLimitInterceptor implements HandlerInterceptor {
    Logger logger= LoggerFactory.getLogger(SatisfactionApi.class);

    @Resource
    private RedisUtil redisUtil;

    private static final String LOCK_IP_URL_KEY = "lock_ip_";

    private static final String IP_URL_REQ_TIME = "ip_url_times_";

    private static final int LIMIT_TIMES = 5;

    private static final int IP_LOCK_TIMES = 180;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ip = IpUtils.getRealIp(request);
        logger.info("preHandler:check ip is locked,{}",ip);
        if (ipIsLock(ip))
        {
            returnJson(response,"请勿频繁操作");
            return false;
        }
        String url = request.getRequestURI();
        if(!addRequestTime(ip,url))
        {
            returnJson(response,"请勿频繁操作");
            return false;
        }
        return true;
    }

    private boolean ipIsLock(String ip)
    {
        if (redisUtil.exist(LOCK_IP_URL_KEY+ip))
        {
            logger.error("{} is locked",LOCK_IP_URL_KEY+ip);
            return true;
        }
        return false;
    }

    private boolean addRequestTime(String ip,String url)
    {
        String key = IP_URL_REQ_TIME+ip+url;
        if (redisUtil.exist(key))
        {
            long time = redisUtil.incr(key,1);
            if (time >= LIMIT_TIMES)
            {
                logger.error("{} is locked",LOCK_IP_URL_KEY+ip);
//                redisUtil.getLock(LOCK_IP_URL_KEY+ip,ip,IP_LOCK_TIMES);
                return false;
            }
        }else {
//            redisUtil.getLock(key,1,10L);
        }
        return true;
    }

    private void returnJson(HttpServletResponse response,String json)
    {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/json;charset=utf-8");
        try(PrintWriter writer = response.getWriter()){
            writer.print(json);
        }catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
